பைதான் சுருக்க அடிப்படை வகுப்புகளின் (ABCs) ஆற்றலை வெளிக்கொணருங்கள். நெறிமுறை அடிப்படையிலான கட்டமைப்பு வகைப்படுத்தல் மற்றும் முறையான இடைமுக வடிவமைப்பிற்கு இடையிலான முக்கிய வேறுபாட்டைப் புரிந்துகொள்ளுங்கள்.
பைதான் சுருக்க அடிப்படை வகுப்புகள்: நெறிமுறை செயலாக்கம் மற்றும் இடைமுக வடிவமைப்புக்கு இடையே உள்ள வேறுபாட்டைக் கற்றுக்கொள்வது
மென்பொருள் மேம்பாட்டு உலகில், வலுவான, பராமரிக்கக்கூடிய மற்றும் அளவிடக்கூடிய பயன்பாடுகளை உருவாக்குவதே இறுதி இலக்கு. திட்டங்கள் சில ஸ்கிரிப்ட்களில் இருந்து சர்வதேச அணிகளால் நிர்வகிக்கப்படும் சிக்கலான அமைப்புகளாக வளரும்போது, தெளிவான கட்டமைப்பு மற்றும் கணிக்கக்கூடிய ஒப்பந்தங்களின் தேவை மிக முக்கியமானது. வெவ்வேறு நேர மண்டலங்களில் வெவ்வேறு டெவலப்பர்களால் எழுதப்பட்ட வெவ்வேறு கூறுகள் தடையின்றி மற்றும் நம்பகத்தன்மையுடன் செயல்படுவதை நாம் எவ்வாறு உறுதிப்படுத்துவது? சுருக்கக் கொள்கையில் இதற்கான பதில் உள்ளது.
பைதான், அதன் மாறும் தன்மை காரணமாக, சுருக்கத்திற்கான ஒரு பிரபலமான தத்துவத்தைக் கொண்டுள்ளது: "டக் டைப்பிங்". ஒரு பொருள் வாத்து போல நடந்தால் மற்றும் வாத்து போல சத்தமிட்டால், அதை நாம் ஒரு வாத்து என்று கருதுகிறோம். இந்த நெகிழ்வுத்தன்மை பைதானின் மிகப்பெரிய பலங்களில் ஒன்றாகும், இது விரைவான வளர்ச்சி மற்றும் சுத்தமான, படிக்கக்கூடிய குறியீட்டை ஊக்குவிக்கிறது. இருப்பினும், பெரிய அளவிலான பயன்பாடுகளில், மறைமுக ஒப்பந்தங்களை மட்டுமே நம்பியிருப்பது நுட்பமான பிழைகள் மற்றும் பராமரிப்பு சிக்கல்களுக்கு வழிவகுக்கும். ஒரு 'வாத்து' எதிர்பாராத விதமாக பறக்க முடியாவிட்டால் என்ன நடக்கும்? பைதானின் சுருக்க அடிப்படை வகுப்புகள் (ABCs) இந்த இடத்தில் நுழைகின்றன, பைதானின் மாறும் தன்மையைத் தியாகம் செய்யாமல் முறையான ஒப்பந்தங்களை உருவாக்க ஒரு சக்திவாய்ந்த பொறிமுறையை வழங்குகின்றன.
ஆனால் இங்கு ஒரு முக்கியமான மற்றும் பெரும்பாலும் தவறாகப் புரிந்துகொள்ளப்பட்ட வேறுபாடு உள்ளது. பைதானில் உள்ள ABCகள் ஒரு அனைத்து அளவுகளுக்கும் பொருந்தக்கூடிய கருவி அல்ல. அவை மென்பொருள் வடிவமைப்பின் இரண்டு தனித்துவமான, சக்திவாய்ந்த தத்துவங்களுக்கு உதவுகின்றன: பரம்பரைத் தேவைப்படும் வெளிப்படையான, முறையான இடைமுகங்களை உருவாக்குதல், மற்றும் திறன்களைச் சரிபார்க்கும் நெகிழ்வான நெறிமுறைகளை வரையறுத்தல். இந்த இரண்டு அணுகுமுறைகளுக்கும் இடையிலான வேறுபாட்டைப் புரிந்துகொள்வது—இடைமுக வடிவமைப்பு மற்றும் நெறிமுறை செயலாக்கம்—பைதானில் பொருள் சார்ந்த வடிவமைப்பின் முழு திறனையும் திறப்பதற்கும், நெகிழ்வான மற்றும் பாதுகாப்பான குறியீட்டை எழுதுவதற்கும் முக்கியமாகும். இந்த வழிகாட்டி இரண்டு தத்துவங்களையும் ஆராய்ந்து, உங்கள் உலகளாவிய மென்பொருள் திட்டங்களில் ஒவ்வொரு அணுகுமுறையையும் எப்போது பயன்படுத்த வேண்டும் என்பதற்கான நடைமுறை எடுத்துக்காட்டுகள் மற்றும் தெளிவான வழிகாட்டுதல்களை வழங்கும்.
வடிவமைப்பு குறித்த குறிப்பு: குறிப்பிட்ட வடிவமைப்பு கட்டுப்பாடுகளுக்கு இணங்க, இந்தக் கட்டுரையில் குறியீடு எடுத்துக்காட்டுகள் தடித்த மற்றும் சாய்ந்த பாணிகளைப் பயன்படுத்தி நிலையான உரை குறிச்சொற்களுக்குள் வழங்கப்படுகின்றன. சிறந்த படிக்கக்கூடிய தன்மைக்கு அவற்றை உங்கள் எடிட்டரில் நகலெடுக்க பரிந்துரைக்கிறோம்.
அடித்தளம்: சுருக்க அடிப்படை வகுப்புகள் என்றால் என்ன?
இரண்டு வடிவமைப்பு தத்துவங்களுக்குள் செல்வதற்கு முன், ஒரு உறுதியான அடித்தளத்தை அமைப்போம். சுருக்க அடிப்படை வகுப்பு என்றால் என்ன? அதன் மையத்தில், ஒரு ABC என்பது பிற வகுப்புகளுக்கான ஒரு நீல அச்சு ஆகும். இது எந்தவொரு இணக்கமான துணைக் வகுப்பும் செயல்படுத்த வேண்டிய முறைகள் மற்றும் பண்புகளின் தொகுப்பை வரையறுக்கிறது. "இந்தக் குடும்பத்தின் ஒரு பகுதி" என்று கூறும் எந்தவொரு வகுப்பிற்கும் இந்த குறிப்பிட்ட திறன்கள் இருக்க வேண்டும் என்று சொல்வதற்கு இது ஒரு வழி.
பைதானின் உள்ளமைக்கப்பட்ட `abc` தொகுதி ABCகளை உருவாக்க கருவிகளை வழங்குகிறது. இரண்டு முதன்மை கூறுகள்:
- `ABC`: ஒரு ABCஐ உருவாக்க ஒரு மெட்டாகிளாஸாகப் பயன்படுத்தப்படும் ஒரு உதவி வகுப்பு. நவீன பைதானில் (3.4+), நீங்கள் வெறுமனே `abc.ABC` இலிருந்து பரம்பரை பெறலாம்.
- `@abstractmethod`: முறைகளை சுருக்கமாகக் குறிக்கப் பயன்படும் ஒரு அலங்கரிப்பான். ABCயின் எந்தவொரு துணைக் வகுப்பும் இந்த முறைகளைச் செயல்படுத்த வேண்டும்.
ABCகளை நிர்வகிக்கும் இரண்டு அடிப்படை விதிகள் உள்ளன:
- செயல்படுத்தப்படாத சுருக்க முறைகளைக் கொண்ட ஒரு ABCயின் நிகழ்வை நீங்கள் உருவாக்க முடியாது. இது ஒரு டெம்ப்ளேட், முடிக்கப்பட்ட தயாரிப்பு அல்ல.
- எந்தவொரு உறுதியான துணைக் வகுப்பும் பரம்பரை பெற்ற அனைத்து சுருக்க முறைகளையும் செயல்படுத்த வேண்டும். அவ்வாறு செய்யத் தவறினால், அதுவும் ஒரு சுருக்க வகுப்பாக மாறும், மேலும் அதன் நிகழ்வை நீங்கள் உருவாக்க முடியாது.
மீடியா கோப்புகளைக் கையாளும் ஒரு அமைப்புக்கான ஒரு உன்னதமான எடுத்துக்காட்டுடன் இதை நடைமுறையில் பார்ப்போம்.
எடுத்துக்காட்டு: ஒரு எளிய MediaFile ABC
பல்வேறு வகையான மீடியாவைக் கையாள வேண்டிய ஒரு பயன்பாட்டை நாம் உருவாக்குகிறோம் என்று கற்பனை செய்யுங்கள். ஒவ்வொரு மீடியா கோப்பும், அதன் வடிவத்தைப் பொருட்படுத்தாமல், இயக்கக்கூடியதாக இருக்க வேண்டும் மற்றும் சில மெட்டாடேட்டாவைக் கொண்டிருக்க வேண்டும் என்று நமக்குத் தெரியும். இந்த ஒப்பந்தத்தை ஒரு ABC உடன் நாம் வரையறுக்கலாம்.
import abc
class MediaFile(abc.ABC):
def __init__(self, filepath: str):
self.filepath = filepath
print(f"Base init for {self.filepath}")
@abc.abstractmethod
def play(self) -> None:
"""மீடியா கோப்பை இயக்கு."""
raise NotImplementedError
@abc.abstractmethod
def get_metadata(self) -> dict:
"""மீடியா மெட்டாடேட்டாவின் அகராதியைத் திருப்பு."""
raise NotImplementedError
நாம் `MediaFile` இன் ஒரு நிகழ்வை நேரடியாக உருவாக்க முயற்சித்தால், பைதான் நம்மை நிறுத்தும்:
# இது ஒரு TypeError ஐ எழுப்பும்
# media = MediaFile("path/to/somefile.txt")
# TypeError: Can't instantiate abstract class MediaFile with abstract methods get_metadata, play
இந்த நீல அச்சை பயன்படுத்த, நாம் `play()` மற்றும் `get_metadata()` க்கான செயலாக்கங்களை வழங்கும் உறுதியான துணைக் வகுப்புகளை உருவாக்க வேண்டும்.
class AudioFile(MediaFile):
def play(self) -> None:
print(f"{self.filepath} இலிருந்து ஆடியோவை இயக்குகிறது...")
def get_metadata(self) -> dict:
return {"codec": "mp3", "duration_seconds": 180}
class VideoFile(MediaFile):
def play(self) -> None:
print(f"{self.filepath} இலிருந்து வீடியோவை இயக்குகிறது...")
def get_metadata(self) -> dict:
return {"codec": "h264", "resolution": "1920x1080"}
இப்போது, `AudioFile` மற்றும் `VideoFile` இன் நிகழ்வுகளை நாம் உருவாக்க முடியும், ஏனெனில் அவை `MediaFile` ஆல் வரையறுக்கப்பட்ட ஒப்பந்தத்தை பூர்த்தி செய்கின்றன. இது ABCகளின் அடிப்படை பொறிமுறை. ஆனால் உண்மையான சக்தி இந்த பொறிமுறையை நாம் *எவ்வாறு* பயன்படுத்துகிறோம் என்பதிலிருந்து வருகிறது.
முதல் தத்துவம்: முறையான இடைமுக வடிவமைப்பாக ABCகள் (பெயரிடப்பட்ட வகைப்படுத்தல்)
ABCs ஐப் பயன்படுத்தும் முதல் மற்றும் மிகவும் பாரம்பரியமான வழி முறையான இடைமுக வடிவமைப்பிற்கானது. இந்த அணுகுமுறை பெயரிடப்பட்ட வகைப்படுத்தலில் வேரூன்றியுள்ளது, இது ஜாவா, சி++, அல்லது சி# போன்ற மொழிகளிலிருந்து வரும் டெவலப்பர்களுக்கு நன்கு தெரிந்த ஒரு கருத்து. ஒரு பெயரிடப்பட்ட அமைப்பில், ஒரு வகையின் இணக்கம் அதன் பெயர் மற்றும் வெளிப்படையான அறிவிப்பால் தீர்மானிக்கப்படுகிறது. நம் சூழலில், ஒரு வகுப்பு `MediaFile` ABC இலிருந்து வெளிப்படையாக பரம்பரை பெற்றால் மட்டுமே `MediaFile` ஆகக் கருதப்படுகிறது.
இதை ஒரு தொழில்முறை சான்றிதழ் போல நினைத்துப் பாருங்கள். சான்றளிக்கப்பட்ட திட்ட மேலாளராக இருக்க, நீங்கள் ஒருவராக செயல்பட்டால் மட்டும் போதாது; நீங்கள் ஒரு குறிப்பிட்ட தேர்வில் படித்து, தேர்ச்சி பெற்று, உங்கள் தகுதியை வெளிப்படையாகக் கூறும் அதிகாரப்பூர்வ சான்றிதழைப் பெற வேண்டும். உங்கள் சான்றிதழின் பெயர் மற்றும் வம்சாவளி முக்கியம்.
இந்த மாதிரியில், ABC ஒரு பேச்சுவார்த்தைக்குட்படாத ஒப்பந்தமாக செயல்படுகிறது. அதிலிருந்து பரம்பரை பெறுவதன் மூலம், ஒரு வகுப்பு மீதமுள்ள அமைப்புக்கு தேவையான செயல்பாடுகளை வழங்கும் என்று ஒரு முறையான வாக்குறுதியை அளிக்கிறது.
எடுத்துக்காட்டு: ஒரு தரவு ஏற்றுமதி கட்டமைப்பு
பயனர்கள் தரவை பல்வேறு வடிவங்களுக்கு ஏற்றுமதி செய்ய அனுமதிக்கும் ஒரு கட்டமைப்பை நாம் உருவாக்குகிறோம் என்று கற்பனை செய்யுங்கள். ஒவ்வொரு ஏற்றுமதி செருகுநிரலும் ஒரு கடுமையான கட்டமைப்பிற்கு இணங்குவதை நாம் உறுதிப்படுத்த விரும்புகிறோம். நாம் ஒரு `DataExporter` இடைமுகத்தை வரையறுக்கலாம்.
import abc
from datetime import datetime
class DataExporter(abc.ABC):
"""தரவு ஏற்றுமதி வகுப்புகளுக்கான ஒரு முறையான இடைமுகம்."""
@abc.abstractmethod
def export(self, data: list[dict]) -> str:
"""தரவை ஏற்றுமதி செய்து ஒரு நிலை செய்தியைத் திருப்புகிறது."""
pass
def get_timestamp(self) -> str:
"""அனைத்து துணைக் வகுப்புகளாலும் பகிரப்பட்ட ஒரு உறுதியான உதவி முறை."""
return datetime.utcnow().isoformat()
class CSVExporter(DataExporter):
def export(self, data: list[dict]) -> str:
filename = f"export_{self.get_timestamp()}.csv"
print(f"Exporting {len(data)} rows to {filename}")
# ... உண்மையான CSV எழுதும் தர்க்கம் ...
return f"Successfully exported to {filename}"
class JSONExporter(DataExporter):
def export(self, data: list[dict]) -> str:
filename = f"export_{self.get_timestamp()}.json"
print(f"Exporting {len(data)} records to {filename}")
# ... உண்மையான JSON எழுதும் தர்க்கம் ...
return f"Successfully exported to {filename}"
இங்கு, `CSVExporter` மற்றும் `JSONExporter` ஆகியவை வெளிப்படையாகவும் சரிபார்க்கக்கூடிய வகையிலும் `DataExporter`கள். எங்கள் பயன்பாட்டின் முக்கிய தர்க்கம் இந்த ஒப்பந்தத்தை பாதுகாப்பாக நம்பலாம்:
def run_export_process(exporter: DataExporter, data_to_export: list[dict]):
print("--- ஏற்றுமதி செயல்முறை தொடங்குகிறது ---")
if not isinstance(exporter, DataExporter):
raise TypeError("ஏற்றுமதியாளர் ஒரு செல்லுபடியாகும் DataExporter செயலாக்கமாக இருக்க வேண்டும்.")
status = exporter.export(data_to_export)
print(f"செயல்முறை நிலை: {status} உடன் முடிந்தது")
# பயன்பாடு
data = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
run_export_process(CSVExporter(), data)
run_export_process(JSONExporter(), data)
ABC ஒரு உறுதியான முறை, `get_timestamp()`, ஐயும் வழங்குகிறது என்பதைக் கவனியுங்கள், இது அதன் அனைத்து குழந்தைகளுக்குக்கும் பகிரப்பட்ட செயல்பாட்டை வழங்குகிறது. இது இடைமுக அடிப்படையிலான வடிவமைப்பில் ஒரு பொதுவான மற்றும் சக்திவாய்ந்த முறை.
முறையான இடைமுக அணுகுமுறையின் நன்மை தீமைகள்
நன்மைகள்:
- சந்தேகமற்ற மற்றும் வெளிப்படையானது: ஒப்பந்தம் மிகவும் தெளிவாக உள்ளது. ஒரு டெவலப்பர் `class CSVExporter(DataExporter):` என்ற பரம்பரை வரிசையைப் பார்த்து உடனடியாக வகுப்பின் பங்கு மற்றும் திறன்களைப் புரிந்துகொள்ள முடியும்.
- கருவிக்கு ஏற்றது: IDEகள், லின்டர்கள் மற்றும் நிலையான பகுப்பாய்வு கருவிகள் ஒப்பந்தத்தை எளிதாக சரிபார்க்கலாம், சிறந்த தானியங்கு நிறைவு மற்றும் பிழை சரிபார்ப்பை வழங்குகின்றன.
- பகிரப்பட்ட செயல்பாடு: ABCகள் உறுதியான முறைகளை வழங்க முடியும், இது ஒரு உண்மையான அடிப்படை வகுப்பாக செயல்பட்டு குறியீடு நகலை குறைக்கிறது.
- பழக்கவழக்கம்: இந்த முறை மற்ற பொருள் சார்ந்த மொழிகளில் பெரும்பாலான டெவலப்பர்களுக்கு உடனடியாக அடையாளம் காணக்கூடியது.
தீமைகள்:
- கடுமையான பிணைப்பு: உறுதியான வகுப்பு இப்போது ABC உடன் நேரடியாக பிணைக்கப்பட்டுள்ளது. ABC ஐ நகர்த்தவோ அல்லது மாற்றவோ தேவைப்பட்டால், அனைத்து துணைக் வகுப்புகளும் பாதிக்கப்படும்.
- கடுமை: இது ஒரு கடுமையான படிநிலை உறவை கட்டாயப்படுத்துகிறது. ஒரு வகுப்பு தர்க்கரீதியாக ஒரு ஏற்றுமதியாளராக செயல்பட முடிந்தால் என்ன ஆகும், ஆனால் ஏற்கனவே வேறு ஒரு அத்தியாவசிய அடிப்படை வகுப்பிலிருந்து பரம்பரை பெற்றுள்ளது? பைதானின் பல பரம்பரை இதை தீர்க்க முடியும், ஆனால் அது அதன் சொந்த சிக்கல்களையும் (டயமண்ட் சிக்கல் போன்றவை) அறிமுகப்படுத்தலாம்.
- ஊடுருவும் தன்மை: மூன்றாம் தரப்பு குறியீட்டை மாற்றியமைக்க இதைப் பயன்படுத்த முடியாது. `export()` முறையுடன் ஒரு வகுப்பை வழங்கும் ஒரு நூலகத்தை நீங்கள் பயன்படுத்தினால், அதை துணைக் வகுப்பாக்காமல் (இது சாத்தியமில்லை அல்லது விரும்பத்தக்கது அல்ல) `DataExporter` ஆக மாற்ற முடியாது.
இரண்டாவது தத்துவம்: நெறிமுறை செயலாக்கமாக ABCகள் (கட்டமைப்பு வகைப்படுத்தல்)
இரண்டாவது, மேலும் "பைதான் போன்ற" தத்துவம் டக் டைப்பிங்குடன் ஒத்துப்போகிறது. இந்த அணுகுமுறை கட்டமைப்பு வகைப்படுத்தலை பயன்படுத்துகிறது, அங்கு இணக்கம் பெயர் அல்லது மரபு மூலம் தீர்மானிக்கப்படுவதில்லை, மாறாக கட்டமைப்பு மற்றும் நடத்தை மூலம் தீர்மானிக்கப்படுகிறது. ஒரு பொருள் வேலையைச் செய்ய தேவையான முறைகள் மற்றும் பண்புகளைக் கொண்டிருந்தால், அது அதன் அறிவிக்கப்பட்ட வகுப்பு படிநிலையைப் பொருட்படுத்தாமல், வேலைக்கான சரியான வகையாகக் கருதப்படுகிறது.
நீந்தும் திறனைப் பற்றி யோசித்துப் பாருங்கள். ஒரு நீச்சல் வீரராகக் கருதப்பட, உங்களுக்கு ஒரு சான்றிதழ் தேவையில்லை அல்லது "நீச்சல் வீரர்" குடும்ப மரத்தின் ஒரு பகுதியாக இருக்க வேண்டியதில்லை. நீங்கள் மூழ்காமல் தண்ணீரில் உங்களை நகர்த்த முடிந்தால், நீங்கள், கட்டமைப்பு ரீதியாக, ஒரு நீச்சல் வீரர். ஒரு நபர், ஒரு நாய் மற்றும் ஒரு வாத்து அனைவரும் நீச்சல் வீரர்களாக இருக்க முடியும்.
இந்த கருத்தை முறையானதாக்க ABCகள் பயன்படுத்தப்படலாம். பரம்பரையை கட்டாயப்படுத்துவதற்குப் பதிலாக, தேவையான நெறிமுறையைச் செயல்படுத்தினால், பிற வகுப்புகளை அதன் மெய்நிகர் துணைக் வகுப்புகளாக அங்கீகரிக்கும் ஒரு ABC ஐ நாம் வரையறுக்கலாம். இது ஒரு சிறப்பு மாயாஜால முறை மூலம் அடையப்படுகிறது: `__subclasshook__`.
நீங்கள் `isinstance(obj, MyABC)` அல்லது `issubclass(SomeClass, MyABC)` ஐ அழைக்கும்போது, பைதான் முதலில் வெளிப்படையான பரம்பரையை சரிபார்க்கிறது. அது தோல்வியுற்றால், அது `MyABC` ஒரு `__subclasshook__` முறையைக் கொண்டிருக்கிறதா என்று சரிபார்க்கிறது. அவ்வாறு இருந்தால், பைதான் அதை அழைத்து, "ஹே, இந்த வகுப்பை உங்கள் துணைக் வகுப்பாக கருதுகிறீர்களா?" என்று கேட்கிறது. இது ABC அதன் உறுப்பினர் அளவுகோல்களை கட்டமைப்பின் அடிப்படையில் வரையறுக்க அனுமதிக்கிறது.
எடுத்துக்காட்டு: ஒரு `Serializable` நெறிமுறை
ஒரு அகராதிக்கு தொடர் வரிசைப்படுத்தக்கூடிய பொருள்களுக்கான ஒரு நெறிமுறையை வரையறுப்போம். எங்கள் கணினியில் உள்ள ஒவ்வொரு தொடர் வரிசைப்படுத்தக்கூடிய பொருளையும் ஒரு பொதுவான அடிப்படை வகுப்பிலிருந்து பரம்பரை பெறும்படி கட்டாயப்படுத்த நாங்கள் விரும்பவில்லை. அவை தரவுத்தள மாதிரிகள், தரவு பரிமாற்ற பொருள்கள் அல்லது எளிய கொள்கலன்களாக இருக்கலாம்.
import abc
class Serializable(abc.ABC):
@abc.abstractmethod
def to_dict(self) -> dict:
pass
@classmethod
def __subclasshook__(cls, C):
if cls is Serializable:
# C இன் முறைத் தீர்வு வரிசையில் 'to_dict' உள்ளதா என சரிபார்க்கவும்
if any("to_dict" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
இப்போது, சில வகுப்புகளை உருவாக்குவோம். முக்கியமாக, அவற்றில் எதுவும் `Serializable` இலிருந்து பரம்பரை பெறாது.
class User:
def __init__(self, name: str, email: str):
self.name = name
self.email = email
def to_dict(self) -> dict:
return {"name": self.name, "email": self.email}
class Product:
def __init__(self, sku: str, price: float):
self.sku = sku
self.price = price
# இந்த வகுப்பு நெறிமுறைக்கு இணங்கவில்லை
class Configuration:
def __init__(self, setting: str):
self.setting = setting
எங்கள் நெறிமுறைக்கு எதிராக அவற்றை சரிபார்ப்போம்:
print(f"பயனர் தொடர் வரிசைப்படுத்தக்கூடியதா? {isinstance(User('Test', 't@t.com'), Serializable)}")
print(f"தயாரிப்பு தொடர் வரிசைப்படுத்தக்கூடியதா? {isinstance(Product('T-1000', 99.99), Serializable)}")
print(f"கட்டமைப்பு தொடர் வரிசைப்படுத்தக்கூடியதா? {isinstance(Configuration('ON'), Serializable)}")
# வெளியீடு:
# பயனர் தொடர் வரிசைப்படுத்தக்கூடியதா? True
# தயாரிப்பு தொடர் வரிசைப்படுத்தக்கூடியதா? False <- காத்திருங்கள், ஏன்? இதை சரிசெய்வோம்.
# கட்டமைப்பு தொடர் வரிசைப்படுத்தக்கூடியதா? False
அடடா, ஒரு சுவாரஸ்யமான பிழை! எங்கள் `Product` வகுப்பில் `to_dict` முறை இல்லை. அதைச் சேர்ப்போம்.
class Product:
def __init__(self, sku: str, price: float):
self.sku = sku
self.price = price
def to_dict(self) -> dict: # முறையைச் சேர்த்தல்
return {"sku": self.sku, "price": self.price}
print(f"தயாரிப்பு இப்போது தொடர் வரிசைப்படுத்தக்கூடியதா? {isinstance(Product('T-1000', 99.99), Serializable)}")
# வெளியீடு:
# தயாரிப்பு இப்போது தொடர் வரிசைப்படுத்தக்கூடியதா? True
`User` மற்றும் `Product` க்கு பொதுவான பெற்றோர் வகுப்பு ( `object` ஐத் தவிர) எதுவும் இல்லாவிட்டாலும், எங்கள் அமைப்பு இரண்டையும் `Serializable` ஆகக் கருதலாம், ஏனெனில் அவை நெறிமுறையை பூர்த்தி செய்கின்றன. இது பிணைப்பை நீக்குவதற்கு நம்பமுடியாத சக்தி வாய்ந்தது.
நெறிமுறை அணுகுமுறையின் நன்மை தீமைகள்
நன்மைகள்:
- அதிகபட்ச நெகிழ்வுத்தன்மை: மிகவும் தளர்வான பிணைப்பை ஊக்குவிக்கிறது. கூறுகள் நடத்தை பற்றி மட்டுமே கவலை கொள்கின்றன, செயலாக்க வம்சாவளி பற்றி அல்ல.
- தகவமைப்பு: ஏற்கனவே உள்ள குறியீட்டை, குறிப்பாக மூன்றாம் தரப்பு நூலகங்களில் இருந்து, அசல் குறியீட்டை மாற்றாமல் உங்கள் கணினியின் இடைமுகங்களுக்கு ஏற்றவாறு மாற்றியமைக்க இது சரியானது.
- அமைப்பை ஊக்குவிக்கிறது: ஆழமான, கடுமையான பரம்பரை மரங்கள் மூலம் அல்லாமல், சுயாதீன திறன்களிலிருந்து பொருள்கள் உருவாக்கப்படும் ஒரு வடிவமைப்பு பாணியை ஊக்குவிக்கிறது.
தீமைகள்:
- மறைமுக ஒப்பந்தம்: ஒரு வகுப்பு மற்றும் அது செயல்படுத்தும் நெறிமுறைக்கு இடையிலான உறவு வகுப்பு வரையறையிலிருந்து உடனடியாகத் தெளிவாகத் தெரியவில்லை. ஒரு டெவலப்பர் ஒரு `User` பொருள் ஏன் `Serializable` ஆகக் கருதப்படுகிறது என்பதைப் புரிந்துகொள்ள குறியீட்டுத் தளத்தைத் தேட வேண்டியிருக்கலாம்.
- இயக்க நேர செலவு: `isinstance` சரிபார்ப்பு மெதுவாக இருக்கலாம், ஏனெனில் இது `__subclasshook__` ஐ அழைப்பதற்கும், வகுப்பின் முறைகளை சரிபார்ப்பதற்கும் ஆகும்.
- சிக்கலுக்கான சாத்தியம்: நெறிமுறையில் பல முறைகள், வாதங்கள் அல்லது திரும்புதல் வகைகள் இருந்தால் `__subclasshook__` க்குள் உள்ள தர்க்கம் மிகவும் சிக்கலாக மாறும்.
நவீன தொகுப்பு: `typing.Protocol` மற்றும் நிலையான பகுப்பாய்வு
பெரிய அளவிலான அமைப்புகளில் பைதானின் பயன்பாடு அதிகரித்ததால், சிறந்த நிலையான பகுப்பாய்விற்கான விருப்பமும் அதிகரித்தது. `__subclasshook__` அணுகுமுறை சக்தி வாய்ந்தது, ஆனால் இது முற்றிலும் இயக்க நேர பொறிமுறை. குறியீட்டை இயக்குவதற்கு *முன்பே* கட்டமைப்பு வகைப்படுத்தலின் பலன்களை நாம் பெற முடிந்தால் என்ன ஆகும்?
இது PEP 544 இல் `typing.Protocol` அறிமுகப்படுத்த வழிவகுத்தது. இது Mypy, Pyright, அல்லது PyCharm இன் இன்ஸ்பெக்டர் போன்ற நிலையான வகை சரிபார்ப்பாளர்களுக்காக முதன்மையாக நோக்கமாகக் கொண்ட நெறிமுறைகளை வரையறுக்க ஒரு தரப்படுத்தப்பட்ட மற்றும் நேர்த்தியான வழியை வழங்குகிறது.
ஒரு `Protocol` வகுப்பு எங்கள் `__subclasshook__` எடுத்துக்காட்டுக்கு ஒத்ததாக செயல்படுகிறது, ஆனால் boilerplate இல்லாமல். நீங்கள் முறைகள் மற்றும் அவற்றின் கையொப்பங்களை வெறுமனே வரையறுக்கிறீர்கள். பொருந்தும் முறைகள் மற்றும் கையொப்பங்களைக் கொண்ட எந்தவொரு வகுப்பும் ஒரு நிலையான வகை சரிபார்ப்பாளரால் கட்டமைப்பு ரீதியாக இணக்கமானதாகக் கருதப்படும்.
எடுத்துக்காட்டு: ஒரு `Quacker` நெறிமுறை
நவீன கருவிகளுடன் உன்னதமான டக் டைப்பிங் எடுத்துக்காட்டை மீண்டும் பார்ப்போம்.
from typing import Protocol
class Quacker(Protocol):
def quack(self, volume: int) -> str:
"""குவாக்கிங் ஒலியை உருவாக்குகிறது."""
... # குறிப்பு: நெறிமுறை முறையின் உடல் தேவையில்லை
class Duck:
def quack(self, volume: int) -> str:
return f"QUACK! (at volume {volume})"
class Dog:
def bark(self, volume: int) -> str:
return f"WOOF! (at volume {volume})"
def make_sound(animal: Quacker):
print(animal.quack(10))
make_sound(Duck()) # நிலையான பகுப்பாய்வு வெற்றி பெறுகிறது
make_sound(Dog()) # நிலையான பகுப்பாய்வு தோல்வியடைகிறது!
இந்தக் குறியீட்டை Mypy போன்ற ஒரு வகை சரிபார்ப்பாளர் மூலம் நீங்கள் இயக்கினால், அது `make_sound(Dog())` வரியை ஒரு பிழையுடன் குறிக்கும்: `Argument 1 to "make_sound" has incompatible type "Dog"; expected "Quacker"`. `Dog` இல் `quack` முறை இல்லாததால் அது `Quacker` நெறிமுறையை பூர்த்தி செய்யவில்லை என்பதை வகை சரிபார்ப்பாளர் புரிந்துகொள்கிறார். இது குறியீடு செயல்படுத்தப்படுவதற்கு முன்பே பிழையைப் பிடிக்கிறது.
`@runtime_checkable` உடன் இயக்க நேர நெறிமுறைகள்
முன்னிருப்பாக, `typing.Protocol` நிலையான பகுப்பாய்வுக்கு மட்டுமே. இயக்க நேர `isinstance` சரிபார்ப்பில் நீங்கள் அதைப் பயன்படுத்த முயற்சித்தால், உங்களுக்கு ஒரு பிழை கிடைக்கும்.
# isinstance(Duck(), Quacker) # -> TypeError: Protocol 'Quacker' cannot be instantiated
இருப்பினும், `@runtime_checkable` அலங்கரிப்பான் மூலம் நிலையான பகுப்பாய்வு மற்றும் இயக்க நேர நடத்தைக்கு இடையிலான இடைவெளியை நீங்கள் இணைக்கலாம். இது அடிப்படையில் `__subclasshook__` தர்க்கத்தை தானாகவே உருவாக்க பைத்தானுக்குத் தெரிவிக்கிறது.
from typing import Protocol, runtime_checkable
@runtime_checkable
class Quacker(Protocol):
def quack(self, volume: int) -> str: ...
class Duck:
def quack(self, volume: int) -> str: return "..."
print(f"டக் குவாக்கரின் ஒரு நிகழ்வா? {isinstance(Duck(), Quacker)}")
# வெளியீடு:
# டக் குவாக்கரின் ஒரு நிகழ்வா? True
இது உங்களுக்கு இரு உலகங்களின் சிறந்தவற்றையும் வழங்குகிறது: நிலையான பகுப்பாய்வுக்கான சுத்தமான, அறிவிப்பு நெறிமுறை வரையறைகள், மற்றும் தேவைப்படும்போது இயக்க நேர சரிபார்ப்புக்கான விருப்பம். இருப்பினும், நெறிமுறைகளில் இயக்க நேர சரிபார்ப்புகள் நிலையான `isinstance` அழைப்புகளை விட மெதுவாக இருக்கும் என்பதை நினைவில் கொள்ளவும், எனவே அவை விவேகத்துடன் பயன்படுத்தப்பட வேண்டும்.
நடைமுறை முடிவெடுத்தல்: ஒரு உலகளாவிய டெவலப்பரின் வழிகாட்டி
எனவே, நீங்கள் எந்த அணுகுமுறையைத் தேர்ந்தெடுக்க வேண்டும்? பதில் உங்கள் குறிப்பிட்ட பயன்பாட்டு வழையைப் பொறுத்தது. சர்வதேச மென்பொருள் திட்டங்களில் பொதுவான சூழ்நிலைகளின் அடிப்படையில் ஒரு நடைமுறை வழிகாட்டி இங்கே.
காட்சி 1: ஒரு உலகளாவிய SaaS தயாரிப்புக்கான ஒரு செருகுநிரல் கட்டமைப்பை உருவாக்குதல்
உலகம் முழுவதும் உள்ள முதல் மற்றும் மூன்றாம் தரப்பு டெவலப்பர்களால் நீட்டிக்கப்படும் ஒரு அமைப்பை (எ.கா., ஒரு இ-காமர்ஸ் தளம், ஒரு CMS) நீங்கள் வடிவமைக்கிறீர்கள். இந்த செருகுநிரல்கள் உங்கள் முக்கிய பயன்பாட்டுடன் ஆழமாக ஒருங்கிணைக்க வேண்டும்.
- பரிந்துரை: முறையான இடைமுகம் (பெயரிடப்பட்ட `abc.ABC`).
- காரணம்: தெளிவு, ஸ்திரத்தன்மை மற்றும் வெளிப்படைத்தன்மை மிக முக்கியம். செருகுநிரல் டெவலப்பர்கள் உங்கள் `BasePlugin` ABC இலிருந்து பரம்பரை பெறுவதன் மூலம் உணர்வுபூர்வமாகத் தேர்வுசெய்ய வேண்டிய ஒரு பேச்சுவார்த்தைக்குட்படாத ஒப்பந்தம் உங்களுக்குத் தேவை. இது உங்கள் API ஐ சந்தேகமற்றதாக்குகிறது. நீங்கள் அத்தியாவசிய உதவி முறைகளையும் (எ.கா., பதிவு செய்தல், உள்ளமைவை அணுகுதல், சர்வதேசமயமாக்கல்) அடிப்படை வகுப்பில் வழங்கலாம், இது உங்கள் டெவலப்பர் சுற்றுச்சூழல் அமைப்புக்கு ஒரு பெரிய நன்மை.
காட்சி 2: பல, தொடர்பில்லாத APIகளிலிருந்து நிதி தரவை செயலாக்குதல்
உங்கள் ஃபின்டெக் பயன்பாடு பல்வேறு உலகளாவிய கட்டண நுழைவாயில்களில் இருந்து பரிவர்த்தனை தரவை நுகர வேண்டும்: Stripe, PayPal, Adyen, மற்றும் ஒருவேளை லத்தீன் அமெரிக்காவில் Mercado Pago போன்ற ஒரு பிராந்திய வழங்குநரும் இருக்கலாம். அவற்றின் SDKகளால் வழங்கப்படும் பொருள்கள் உங்கள் கட்டுப்பாட்டில் முற்றிலும் இல்லை.
- பரிந்துரை: நெறிமுறை (`typing.Protocol`).
- காரணம்: இந்த மூன்றாம் தரப்பு SDKகளின் மூலக் குறியீட்டை உங்கள் `Transaction` அடிப்படை வகுப்பிலிருந்து பரம்பரை பெறும்படி நீங்கள் மாற்ற முடியாது. இருப்பினும், அவற்றின் ஒவ்வொரு பரிவர்த்தனைப் பொருளிலும் `get_id()`, `get_amount()`, மற்றும் `get_currency()` போன்ற முறைகள் உள்ளன என்று உங்களுக்குத் தெரியும், அவை சற்று வித்தியாசமாக பெயரிடப்பட்டிருந்தாலும் கூட. ஒரு `TransactionProtocol` உடன் Adapter முறையைப் பயன்படுத்தி ஒரு ஒருங்கிணைந்த காட்சியை நீங்கள் உருவாக்கலாம். ஒரு நெறிமுறை உங்களுக்குத் தேவையான தரவின் *வடிவத்தை* வரையறுக்க அனுமதிக்கிறது, இது எந்தவொரு தரவு மூலத்துடனும் செயல்படும் செயலாக்க தர்க்கத்தை எழுத உங்களுக்கு உதவுகிறது, அது நெறிமுறைக்கு ஏற்றவாறு மாற்றியமைக்க முடிந்தால்.
காட்சி 3: ஒரு பெரிய, ஒற்றைப் பழைமை வாய்ந்த பயன்பாட்டை மறுசீரமைத்தல்
ஒரு பழைமை வாய்ந்த ஒற்றைப் பழைமை வாய்ந்த பயன்பாட்டை நவீன மைக்ரோசர்வீஸ்களாக உடைக்கும் பணியில் நீங்கள் ஈடுபட்டுள்ளீர்கள். ஏற்கனவே உள்ள குறியீட்டுத் தளம் ஒரு சிக்கலான வலைப்பின்னல் சார்புகளைக் கொண்டுள்ளது, மேலும் அனைத்தையும் ஒரே நேரத்தில் மீண்டும் எழுதாமல் தெளிவான எல்லைகளை அறிமுகப்படுத்த வேண்டும்.
- பரிந்துரை: கலவை, ஆனால் நெறிமுறைகளை அதிகமாக சார்ந்து இருங்கள்.
- காரணம்: நெறிமுறைகள் படிப்படியாக மறுசீரமைப்புக்கான ஒரு விதிவிலக்கான கருவி. `typing.Protocol` ஐப் பயன்படுத்தி புதிய சேவைகளுக்கு இடையேயான சிறந்த இடைமுகங்களை வரையறுப்பதன் மூலம் நீங்கள் தொடங்கலாம். பின்னர், முக்கிய பழைமை வாய்ந்த குறியீட்டை உடனடியாக மாற்றாமல், ஒற்றைப் பழைமை வாய்ந்த பகுதிகளை இந்த நெறிமுறைகளுக்கு இணங்க மாற்றியமைக்க அடாப்டர்களை எழுதலாம். இது கூறுகளை படிப்படியாகப் பிரிக்க உங்களை அனுமதிக்கிறது. ஒரு கூறு முழுமையாகப் பிரிக்கப்பட்டு நெறிமுறை வழியாக மட்டுமே தொடர்பு கொண்டவுடன், அது அதன் சொந்த சேவையாகப் பிரித்தெடுக்கத் தயாராக உள்ளது. புதிய, சுத்தமான சேவைகளுக்குள் முக்கிய மாதிரிகளை வரையறுக்க முறையான ABCகள் பின்னர் பயன்படுத்தப்படலாம்.
முடிவு: உங்கள் குறியீட்டில் சுருக்கத்தை நெசவு செய்தல்
பைதானின் சுருக்க அடிப்படை வகுப்புகள் மொழியின் நடைமுறை வடிவமைப்பிற்கு ஒரு சான்றாகும். அவை பாரம்பரிய பொருள் சார்ந்த நிரலாக்கத்தின் கட்டமைக்கப்பட்ட ஒழுக்கம் மற்றும் டக் டைப்பிங்கின் மாறும் நெகிழ்வுத்தன்மை இரண்டையும் மதிக்கும் சுருக்கத்திற்கான ஒரு அதிநவீன கருவித்தொகுப்பை வழங்குகின்றன.
ஒரு மறைமுக ஒப்பந்தத்திலிருந்து ஒரு முறையான ஒப்பந்தத்திற்கான பயணம் ஒரு முதிர்ச்சியடைந்த குறியீட்டுத் தளத்தின் அடையாளம். ABCகளின் இரண்டு தத்துவங்களையும் புரிந்துகொள்வதன் மூலம், தூய்மையான, மேலும் பராமரிக்கக்கூடிய மற்றும் அதிக அளவிடக்கூடிய பயன்பாடுகளுக்கு வழிவகுக்கும் தகவலறிந்த கட்டடக்கலை முடிவுகளை நீங்கள் எடுக்கலாம்.
முக்கிய குறிப்புகளை சுருக்கமாகக் கூற:
- முறையான இடைமுக வடிவமைப்பு (பெயரிடப்பட்ட வகைப்படுத்தல்): வெளிப்படையான, சந்தேகமற்ற மற்றும் கண்டுபிடிக்கக்கூடிய ஒப்பந்தம் உங்களுக்குத் தேவைப்படும்போது நேரடி பரம்பரை கொண்ட `abc.ABC` ஐப் பயன்படுத்தவும். இது கட்டமைப்புகள், செருகுநிரல் அமைப்புகள் மற்றும் வகுப்பு படிநிலையை நீங்கள் கட்டுப்படுத்தும் சூழ்நிலைகளுக்கு ஏற்றது. இது ஒரு வகுப்பு அறிவிப்பு மூலம் என்னவாக இருக்கிறது என்பதைப் பற்றியது.
- நெறிமுறை செயலாக்கம் (கட்டமைப்பு வகைப்படுத்தல்): நெகிழ்வுத்தன்மை, பிணைப்பை நீக்குதல் மற்றும் ஏற்கனவே உள்ள குறியீட்டை மாற்றியமைக்கும் திறன் உங்களுக்குத் தேவைப்படும்போது `typing.Protocol` ஐப் பயன்படுத்தவும். இது வெளி நூலகங்களுடன் பணிபுரிவதற்கும், பழைமை வாய்ந்த அமைப்புகளை மறுசீரமைப்பதற்கும், நடத்தை பல்லுருவத்துவத்திற்காக வடிவமைப்பதற்கும் சரியானது. இது ஒரு வகுப்பு அதன் கட்டமைப்பு மூலம் என்ன செய்ய முடியும் என்பதைப் பற்றியது.
ஒரு இடைமுகம் மற்றும் ஒரு நெறிமுறைக்கு இடையேயான தேர்வு ஒரு தொழில்நுட்ப விவரம் மட்டுமல்ல; இது ஒரு அடிப்படை வடிவமைப்பு முடிவு, இது உங்கள் மென்பொருள் எவ்வாறு உருவாகும் என்பதை வடிவமைக்கும். இரண்டிலும் தேர்ச்சி பெறுவதன் மூலம், நீங்கள் பைதான் குறியீட்டை எழுத உங்களை தயார்படுத்துகிறீர்கள், இது சக்தி வாய்ந்தது மற்றும் திறமையானது மட்டுமல்ல, மாற்றத்திற்கு முகங்கொடுக்கும் வகையில் நேர்த்தியானது மற்றும் மீள்தன்மை கொண்டது.